package com.ruoyi.project.utils;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.enums.GaoDeEnum;
import com.ruoyi.common.utils.AddressUtils;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.entity.MapNavResults;
import com.ruoyi.project.system.user.domain.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.SocketUtils;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

@Component
@Slf4j
public class GaoDeMapUtil {

    /**
     * 功能描述: 高德地图Key
     */
    private static final String GAO_DE_KEY = "d73cc951a96637a251a9a2446b48ce9c";

    //申请的账户Key

    /**
     * 功能描述: 根据地址名称得到两个地址间的距离
     *
     * @param start
     *         起始位置
     * @param end
     *         结束位置
     *
     * @return long 两个地址间的距离
     */
    public Long getDistanceByAddress (String start, String end) {
        String startLonLat = this.getLonLat(start).get("data").toString();
        String endLonLat = this.getLonLat(end).get("data").toString();
        Long distance = Long.valueOf(this.getDistance(startLonLat, endLonLat).get("data").toString());
        return distance;
    }

    /**
     * 功能描述: 地址转换为经纬度
     *
     * @param address
     *         地址
     *
     * @return java.lang.String 经纬度
     */
    public AjaxResult getLonLat (String address) {
        try {
            // 返回输入地址address的经纬度信息, 格式是 经度,纬度
            String queryUrl = "http://restapi.amap.com/v3/geocode/geo?key=" + GAO_DE_KEY + "&address=" + address;
            // 高德接口返回的是JSON格式的字符串
            String queryResult = getResponse(queryUrl);
            JSONObject job = JSONObject.parseObject(queryResult);
            JSONObject jobJSON = JSONObject.parseObject(
                    job.get("geocodes").toString().substring(1, job.get("geocodes").toString().length() - 1));
            String LngAndLat = jobJSON.get("location").toString();
            log.info("经纬度为：" + LngAndLat);
            return AjaxResult.success("经纬度转换成功！", LngAndLat);
        } catch (Exception e) {
            return AjaxResult.error(e.toString());
        }
    }

    /**
     * 将经纬度 转换为 地址
     *
     * @param longitude
     *         经度
     * @param latitude
     *         纬度
     *
     * @return 地址名称
     *
     * @throws Exception
     */
    public AjaxResult getAddress (String longitude, String latitude) throws Exception {
        String url;
        try {
            url = "http://restapi.amap.com/v3/geocode/regeo?output=JSON&location=" + longitude + "," + latitude + "&key=" + GAO_DE_KEY + "&radius=0&extensions=base";

            log.info("经度" + longitude);
            log.info("纬度：" + latitude);
            log.info("url:" + url);

            // 高德接口返回的是JSON格式的字符串
            String queryResult = getResponse(url);
            if (ObjectUtils.isEmpty(queryResult)) {
                return AjaxResult.error("查询结果为空");
            }

            // 将获取结果转为json 数据
            JSONObject obj = JSONObject.parseObject(queryResult);
            if (obj.get(GaoDeEnum.STATUS.getCode()).toString().equals(GaoDeEnum.INT_ONE.getCode())) {
                // 如果没有返回-1
                JSONObject reGeoCode = obj.getJSONObject(GaoDeEnum.RE_GEO_CODE.getCode());
                if (reGeoCode.size() > 0) {
                    // 在regeocode中拿到 formatted_address 具体位置
                    String formatted = reGeoCode.get("formatted_address").toString();
                    return AjaxResult.success("地址获取成功！", formatted);

                } else {
                    return AjaxResult.error("未找到相匹配的地址！");
                }
            } else {
                return AjaxResult.error("请求错误！");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            return AjaxResult.error("系统未知异常，请稍后再试");
        }
    }

    /**
     * 功能描述: 根据两个定位点的经纬度算出两点间的距离
     *
     * @param startLonLat
     *         起始经纬度
     * @param endLonLat
     *         结束经纬度（目标经纬度）
     *
     * @return java.lang.Long 两个定位点之间的距离
     */
    public AjaxResult getDistance (String startLonLat, String endLonLat) {
        try {
            // 返回起始地startAddr与目的地endAddr之间的距离，单位：米
            Long result = new Long(0);
            String queryUrl = "http://restapi.amap.com/v3/distance?key=" + GAO_DE_KEY + "&origins=" + startLonLat + "&destination=" + endLonLat;
            String queryResult = getResponse(queryUrl);
            JSONObject job = JSONObject.parseObject(queryResult);
            JSONArray ja = job.getJSONArray("results");
            JSONObject jobO = JSONObject.parseObject(ja.getString(0));
            result = Long.parseLong(jobO.get("distance").toString());
            log.info("距离：" + result);
            return AjaxResult.success("距离计算成功！", result);
        } catch (Exception e) {
            return AjaxResult.error(e.toString());
        }


    }

    /**
     * 功能描述: 发送请求
     *
     * @param serverUrl
     *         请求地址
     *
     * @return java.lang.String
     */
    private static String getResponse (String serverUrl) {
        // 用JAVA发起http请求，并返回json格式的结果
        StringBuffer result = new StringBuffer();
        try {
            URL url = new URL(serverUrl);
            URLConnection conn = url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            in.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    /**
     * 获取地图导航返回值
     *
     * @return
     */
    public MapNavResults getResults (String startCoordinate, String endCoordinate, String applicationKey) {
        String sendGet = HttpRequest.sendGet("https://restapi.amap.com/v3/direction/driving",
                "origin=" + startCoordinate + "&destination=" + endCoordinate + "&key=" + applicationKey
        );
        JSONObject jsonObject = JSONObject.parseObject(sendGet);
        String routeJsonString = jsonObject.get("route").toString();
        JSONObject routeObject = JSONObject.parseObject(routeJsonString);
        JSONArray jsonArray = routeObject.getJSONArray("paths");
        JSONObject zuiJson = jsonArray.getJSONObject(0);
        MapNavResults mapResult = new MapNavResults();
        mapResult.setDistance(zuiJson.get("distance").toString());
        mapResult.setDuration(zuiJson.get("duration").toString());
        mapResult.setTolls(zuiJson.get("tolls").toString());
        return mapResult;
    }

    public static void main (String[] args) throws Exception {
/*        String origin = "104.07,30.67";//出发点经纬度
        String destination = "104.46,29.23";//目的地经纬度
        String key = "d73cc951a96637a251a9a2446b48ce9c";//高德用户key
        GaoDeMapUtil util = new GaoDeMapUtil();
        System.out.println(util.getResults(origin, destination, key).toString());*/
        GaoDeMapUtil util = new GaoDeMapUtil();
       /* String address = AddressUtils.getAddress("211.90.253.130");
        System.out.println(address);
        if(ObjectUtil.isNotEmpty(address)){
            JSONObject jsonObject = JSONObject.parseObject(address);
            if(jsonObject.containsKey("lat") || jsonObject.containsKey("lng")  || jsonObject.containsKey("adcode") ){
                System.out.println(jsonObject.getString("adcode"));
                System.out.println(jsonObject.getString("lat"));
                System.out.println(jsonObject.getString("lng"));
                String province = util.getAdd(jsonObject.getString("lng"), jsonObject.getString("lat"));
                //AjaxResult address1 = util.getAddress(jsonObject.getString("lat"), jsonObject.getString("lng"));
                System.out.println(JSONObject.toJSONString(province));
                JSONObject jsonObject1 = JSONObject.parseObject(province);
                JSONObject json = jsonObject1.getJSONObject("regeocode");
                String address1 = json.getString("formatted_address");
                String infocode = jsonObject1.getString("infocode");
                System.out.println(address1);
                System.out.println(infocode);
            }
        }*/

        String province = util.getAdd("119.6451", "29.1003");

        System.out.println(province);
   /*     GaoDeMapUtil util = new GaoDeMapUtil();
        System.out.println(util.getIpAddr("172.71.178.58"));*/


    }


    public  String getAdd(String lng, String lat)
    {
        String urlString = "http://restapi.amap.com/v3/geocode/regeo?key="+GAO_DE_KEY+"&location="+lng+ "," +lat;
        String res = "";
        BufferedReader in = null;
        try
        {
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line = null;
            while ((line = in.readLine()) != null)
            {
                res += line + "\n";
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                in.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;

    }


    /**
     * 请求ip对应的地址经纬度(腾讯)
     * @return
     */
    public  String   getIpAddr(String  ip){
        String APP_KEY="HLVBZ-HPAWT-JVLX7-VD354-6GZFV-G6F6A";
        String sendGet = HttpRequest.sendGet("https://apis.map.qq.com/ws/location/v1/ip","ip="+ip+"&key="+APP_KEY);
        JSONObject forObject = JSONObject.parseObject(sendGet);
        JSONObject location = forObject.getJSONObject("result").getJSONObject("location");
        Object lat = location.get("lat");
        Object lng = location.get("lng");
        String latLng=lat.toString()+","+lng.toString();
        System.out.println("经纬度"+latLng);
        //获取经纬度对应的地址原来的不详细没有给到街道
        String sendGet1= HttpRequest.sendGet("https://apis.map.qq.com/ws/geocoder/v1/","location=" + latLng + "&key=" + APP_KEY);
        JSONObject forObject1 =JSONObject.parseObject(sendGet1);
        //位置描述
        Object o = forObject1.getJSONObject("result").get("address");
        return  o.toString();
    }


}